package com.ftg.learn.util;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;

/**
 * 阿里云OSS对象存储工具类
 * 提供创建bucket、上传文件、下载文件等通用功能
 *
 * @author 布衣
 */
@SuppressWarnings("unused")
@Component
public class OssUtils {

    /**
     * OSS服务地址
     */
    @Value("${oss.endpoint}")
    private String endpoint;

    /**
     * 访问身份验证中用到用户标识
     */
    @Value("${oss.access-key-id}")
    private String accessKeyId;

    /**
     * 用户用于加密签名字符串和OSS用来验证签名字符串的密钥
     */
    @Value("${oss.access-key-secret}")
    private String accessKeySecret;

    /**
     * 默认存储空间名称
     */
    @Value("${oss.bucket-name}")
    @Getter
    private String bucketName;

    /**
     * 存储区域
     */
    @Value("${oss.region}")
    private String region;

    /**
     * OSS客户端实例
     */
    private OSS ossClient;

    /**
     * 初始化OSS客户端
     */
    @PostConstruct
    public void init() {
        // 创建OSSClient实例，使用V1签名方式（更稳定）
        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//        // 创建OSSClient实例
//        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
//        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
//        OSSClientBuilder ossClientBuilder = new OSSClientBuilder();
//        this.ossClient = ossClientBuilder.build(endpoint, accessKeyId, accessKeySecret, clientBuilderConfiguration);
    }

    /**
     * 创建存储空间
     *
     * @param bucketName 存储空间名称
     * @return 是否创建成功
     */
    public boolean createBucket(String bucketName) {
        try {
            // 创建存储空间
            ossClient.createBucket(bucketName);
            return true;
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("创建Bucket失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传文件字符串内容
     *
     * @param bucketName 存储空间名称
     * @param objectName 文件名称
     * @param content    文件内容
     * @return 是否上传成功
     */
    public boolean putObject(String bucketName, String objectName, String content) {
        Optional<String> optional = Optional.of(bucketName);
        try (InputStream inputStream = new ByteArrayInputStream(content.getBytes())) {
            ossClient.putObject(optional.orElse(this.bucketName), objectName, inputStream);
            return true;
        } catch (OSSException | ClientException | IOException e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传文件输入流
     *
     * @param bucketName  存储空间名称
     * @param objectName  文件名称
     * @param inputStream 文件输入流
     * @return 是否上传成功
     */
    public boolean putObject(String bucketName, String objectName, InputStream inputStream) {
        try {
            ossClient.putObject(bucketName, objectName, inputStream);
            return true;
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传MultipartFile文件
     *
             * @param bucketName 存储空间名称
             * @param objectName 文件名称
             * @param file       MultipartFile文件对象
             * @return 是否上传成功
             */
             public boolean putObject(String bucketName, String objectName, MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            System.out.println(ossClient+"==ossClient>");
            ossClient.putObject(bucketName, objectName, inputStream);
            return true;
        } catch (OSSException | ClientException | IOException e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 下载文件
     *
     * @param bucketName 存储空间名称
     * @param objectName 文件名称
     * @return OSS对象
     */
    public OSSObject getObject(String bucketName, String objectName) {
        try {
            return ossClient.getObject(bucketName, objectName);
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("下载文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 下载文件到本地
     *
     * @param bucketName   存储空间名称
     * @param objectName   文件名称
     * @param localFileUrl 本地保存路径
     * @return 是否下载成功
     */
    public boolean getObjectToFile(String bucketName, String objectName, String localFileUrl) {
        try {
            ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileUrl));
            return true;
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("下载文件到本地失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除文件
     *
     * @param bucketName 存储空间名称
     * @param objectName 文件名称
     * @return 是否删除成功
     */
    public boolean deleteObject(String bucketName, String objectName) {
        try {
            ossClient.deleteObject(bucketName, objectName);
            return true;
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("删除文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除多个文件
     *
     * @param bucketName  存储空间名称
     * @param objectNames 文件名称列表
     * @return 删除结果
     */
    public DeleteObjectsResult deleteObjects(String bucketName, List<String> objectNames) {
        try {
            DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName);
            request.setKeys(objectNames);
            return ossClient.deleteObjects(request);
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("删除多个文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 列出存储空间中的文件
     *
     * @param bucketName 存储空间名称
     * @return 文件列表
     */
    public ObjectListing listObjects(String bucketName) {
        try {
            return ossClient.listObjects(bucketName);
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("列出文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param bucketName 存储空间名称
     * @param objectName 文件名称
     * @return 是否存在
     */
    public boolean doesObjectExist(String bucketName, String objectName) {
        try {
            return ossClient.doesObjectExist(bucketName, objectName);
        } catch (OSSException | ClientException e) {
            throw new RuntimeException("检查文件是否存在失败: " + e.getMessage(), e);
        }
    }

    /**
     * 关闭OSS客户端
     */
    public void shutdown() {
        if (ossClient != null) {
            ossClient.shutdown();
        }
    }


    /**
     * 生成一个唯一的 Bucket 名称
     *
     * @param prefix 名称前缀
     * @return 唯一的Bucket名称
     */
    public static String generateUniqueBucketName(String prefix) {
        // 获取当前时间戳
        String timestamp = String.valueOf(System.currentTimeMillis());
        // 生成一个 0 到 9999 之间的随机数
        java.util.Random random = new java.util.Random();
        int randomNum = random.nextInt(10000);
        // 连接以形成一个唯一的 Bucket 名称
        return prefix + "-" + timestamp + "-" + randomNum;
    }
}
